import React from 'react';
import { Line } from 'react-chartjs-2';
import { Select, Spin, DatePicker, Space } from 'antd';
import './kchart.css'

import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js';
const { Option } = Select;
const { RangePicker } = DatePicker;

const axios = require('axios').default;

function getColors(n) {
  let colors = ["#FF0000", "#FF7D00", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF", "#FF00FF"]
  let result = []
  for (let i = 0; i < n; i++) {
    result.push(colors[i % 7])
  }
  return result
}
function getColorBy(i) {
  let colors = ["#FF0000", "#FF7D00", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF", "#FF00FF"]
  return colors[i % 7]
}

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
);



export const options = {
  responsive: true,
  plugins: {
    legend: {
      position: 'top'
    },
    title: {
      display: false,
      text: 'Chart.js Line Chart',
    },
    tooltip: {
      callbacks: {
        label: function (context) {
          let d = context.dataset.dataInfos[context.dataIndex]
          let pchg = '';
          if(d.pchg) {
            pchg = d.pchg.toFixed(2)
          }
          return [`${d.date}`, `￥${context.dataset.data[context.dataIndex]}`, `${pchg}%`];
        }
      }
    }
  },
};



class Kchart extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      metrix: 'tclose',
      rangeType: 'Days5',
      labels: [],
      values: [],
      stockName: '',
      datasets: [],
      stockOptions: []

    };
    this.setting = {
      period: 'Daily',
      rangeType: 'Days5',
      metrix: 'tclose',
      symbols: ['600645']
    } // vaturnover, tclose
    this.datas = {};
    this.handleData2 = this.handleData2.bind(this);
    this.loadData = this.loadData.bind(this);
    this.handlePeriodChange = this.handlePeriodChange.bind(this)
    this.handleRangeTypeChange = this.handleRangeTypeChange.bind(this)
    this.handleMetrixChange = this.handleMetrixChange.bind(this)
    this.handleStockSearch = this.handleStockSearch.bind(this)
    this.handleStockChange = this.handleStockChange.bind(this)
  }


  componentDidMount() {
    this.loadData()
  }
  showLoading(loading) {
    this.setState({
      loading: loading
    })
  }
  loadData() {
    this.showLoading(true)
    const self = this
    let url = `/api/stock/${this.setting.symbols.join(',')}?startDate=2020-05-01&period=${this.setting.period}&range_type=${this.setting.rangeType}`
    axios.get(url)
      .then(function (response) {
        self.handleData2(response.data)
        self.showLoading(false)
      })
      .catch(function (error) {
        // handle error
        console.log(error);
      })
      .then(function () {
        // always executed
      });
  }

  searchStock() {
    let url = `/api/stock-search?word=${this.setting.word}`
    let self = this
    axios.get(url)
      .then(function (response) {
        self.handleStockSearchResult(response.data)
      })
      .catch(function (error) {
        // handle error
        console.log(error);
      })
      .then(function () {
        // always executed
      });
  }
  handleStockSearchResult(datas) {
    const options = datas.map((d) => <Option key={d.symbol}>{d.name}</Option>)
    this.setState({
      stockOptions: options
    })
  }
  normalized(arr) {
    let min = 1000000
    for(let i=0; i<arr.length; i++){
      if(arr[i]<min && arr[i] != 0) {
        min = arr[i]
      }
    }
    return arr.map(e => {
      if(e == 0) {
        return null
      } else {
        return e/min
      }
    })
    // return arr
  }

  handleDatasets() {

    let datasets = this.state.datasets
    for (let i = 0; i < datasets.length; i++) {
      let ds = datasets[i]
      ds.data = ds.dataInfos.map(e => e[this.setting.metrix])
    }
    let newDs = []
    for (let i = 0; i < datasets.length; i++) {
      newDs.push(datasets[i])
    }
    this.setState({
      datasets: newDs
    })
  }

  handleData2(data) {
    let datasets = []
    let i = 0
    let labels = []
    for (var code in data) {
      let d = data[code]
      labels = split(d.map(e => e.date))
      let datas = this.normalized(d.map(e => e[this.setting.metrix]))
      let stockName = d[i].name
      datasets.push({
        label: stockName,
        code: d[i].code,
        data: datas,
        dataInfos: d,
        borderColor: getColorBy(i),
        backgroundColor: 'rgba(255, 99, 132, 0.5)'
      })

      i++
    }

    this.setState({
      labels: labels,
      datasets: datasets
    })

  }
  handleMetrixChange(metrix) {
    this.setting.metrix = metrix
    this.handleDatasets()
  }
  handlePeriodChange(period) {
    this.setting.period = period
    this.loadData()
  }
  handleRangeTypeChange(rangeType) {
    this.setState({
      rangeType: rangeType
    })
    this.setting.rangeType = rangeType
    this.loadData()
  }
  handleStockSearch(word) {
    this.setting.word = word
    this.searchStock()
  }
  handleStockChange(symbol){
    this.setting.symbols.push(symbol)
    this.loadData()
  }
  render() {
    const labels = this.state.labels
    const datasets = this.state.datasets
    const data = {
      labels,
      datasets: datasets,
    };
    return (
      <div className='content' style={{ width: '1000px', padding: '10px' }}>

        <label>股票</label>
        <Select
          size='small'
          showSearch={true}
          placeholder='搜素股票'
          defaultActiveFirstOption={false}
          showArrow={false}
          filterOption={false}
          notFoundContent={null}
          onSearch={this.handleStockSearch}
          onChange={this.handleStockChange}
          style={{width: 160, paddingRight: 5}}
        >
          {this.state.stockOptions}
        </Select>

        <label>指标</label>
        <Select
          size='small'
          defaultValue="tclose"
          style={{
            width: 120,
            paddingRight: 5
          }}
          onChange={this.handleMetrixChange}
        >
          <Option value="tclose">价格</Option>
          <Option value="vaturnover">成交金额</Option>
        </Select>

        <label>日期</label>
        <Select
          size='small'
          defaultValue="Days5"
          style={{
            width: 120,
            paddingRight: 5
          }}
          onChange={this.handleRangeTypeChange}
        >
          <Option value="Custom">自定义</Option>
          <Option value="Days5">5日线</Option>
          <Option value="Days20">20日线</Option>
          <Option value="Days60">60日线</Option>
        </Select>

        {
          this.state.rangeType == 'Custom' ? <RangePicker /> : ''
        }


        <label>周期频率</label>
        <Select
          size='small'
          defaultValue="Daily"
          style={{
            width: 120,
            paddingRight: 5
          }}
          onChange={this.handlePeriodChange}
        >
          <Option value="Daily">日线</Option>
          <Option value="Weekly">周线</Option>
          <Option value="Monthly">月线</Option>
          <Option value="Yearly">年线</Option>
        </Select>
        <div style={{paddingTop: 5}}>
        <label>统计信息</label>
        <Select
          size='small'
          defaultValue="avg"
          style={{
            width: 120,
          }}

        >
          <Option value="avg">平均数</Option>
          <Option value="medeum">中位数</Option>
          <Option value="mod">众数</Option>
          <Option value="max">最大</Option>
          <Option value="min">最小</Option>
        </Select>
        </div>
        {
          this.state.loading ?
            <div className="k-loading">
              <Spin />
            </div>
            :
            <Line options={options} data={data} />
        }



      </div>
    )
  }

}

function split(arr, n = 9) {
  if (arr.length <= 9) {
    return arr
  }
  let avg = parseInt(arr.length / (n - 1))
  let res = []
  for (let i = 0; i < arr.length; i++) {
    if (i == 0 || i == arr.length - 1 || i % avg == 0) {
      res.push(arr[i])
    }
    else {
      res.push('')
    }
  }
  return res

}

export default Kchart;